/*
 *    Copyright © OpenAtom Foundation.
 *
 *    Licensed under the Apache License, Version 2.0 (the "License");
 *    you may not use this file except in compliance with the License.
 *    You may obtain a copy of the License at
 *
 *         http://www.apache.org/licenses/LICENSE-2.0
 *
 *    Unless required by applicable law or agreed to in writing, software
 *    distributed under the License is distributed on an "AS IS" BASIS,
 *    WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 *    See the License for the specific language governing permissions and
 *    limitations under the License.
 */

package com.inspur.edp.bef.bizentity.common;

import com.inspur.edp.bef.bizentity.GspBusinessEntity;
import com.inspur.edp.bef.bizentity.beenum.BETriggerTimePointType;
import com.inspur.edp.bef.bizentity.beenum.RequestNodeTriggerType;
import com.inspur.edp.bef.bizentity.operation.BizOperation;
import com.inspur.edp.bef.bizentity.operation.Determination;
import com.inspur.edp.cef.designtime.api.IGspCommonField;
import com.inspur.edp.cef.designtime.api.element.GspElementDataType;
import com.inspur.edp.cef.designtime.api.variable.CommonVariable;
import java.util.EnumSet;
import java.util.UUID;

/**
 * 业务实体动作工具类
 *
 * @author haoxiaofei
 */
public class BizEntityAtionUtil {

    /**
     * 保存前构件ID
     */
    private static final String BEFORESAVE_COMPONENTID = "50914966-674a-43d5-9935-df726cfd51a6";

    /**
     * 删除构件ID
     */
    private static final String DELETE_COMPONENTID = "d4h18e5f-4cq7-497g-b018-s41220zv145k";

    /**
     * 保存前联动计算ID
     */
    private static final String BEFORESAVE_DETERMINATION_ID = "6b3f4f6a-26f2-4199-8159-e36435c63245";

    /**
     * 删除联动计算ID
     */
    private static final String DELETE_DETERMINATION_ID = "0e7d3731-049b-49b9-9e46-2046ef957843";

    /**
     * 将业务实体中添加动作
     *
     * @param be 业务实体
     */
    public final static void addActions(GspBusinessEntity be) {
        addDeterminations(be);
        addVariables(be);
    }

    /**
     * 获取联动计算（事件）
     *
     * @param code 编号
     * @param name 名称
     * @param componentName 构件名称
     * @param componentId 构件ID
     * @param timePointType 触发时间
     * @param triggerType 触发方式
     * @return 联动计算
     */
    private static Determination getDetermination(String code, String name, String componentName,
        String componentId, EnumSet<BETriggerTimePointType> timePointType,
        EnumSet<RequestNodeTriggerType> triggerType) {
        Determination dtm = new Determination();
        dtm.setID(UUID.randomUUID().toString());
        dtm.setCode(code);
        dtm.setName(name);
        dtm.setComponentId(componentId);
        dtm.setComponentName(componentName);
        dtm.setTriggerTimePointType(timePointType);

        dtm.setRequestNodeTriggerType(triggerType);
        return dtm;
    }

    /**
     * 判断联动计算是否存在
     *
     * @param be 业务实体
     * @param actionId 动作ID
     * @return 是否存在
     */
    private static boolean isExistedDtm(GspBusinessEntity be, String actionId) {
        boolean isExist = false;
        if (be.getMainObject().getDeterminations() == null
            || be.getMainObject().getDeterminations().size() == 0) {
            isExist = false;
        }
        for (BizOperation action : be.getMainObject().getDeterminations()) {
            if (actionId.equals(action.getID())) {
                isExist = true;
                break;
            }
        }
        return isExist;
    }

    /**
     * 添加联动计算
     *
     * @param be 业务实体
     */
    public static void addDeterminations(GspBusinessEntity be) {
        boolean isExistedBeforeSave = isExistedDtm(be, BEFORESAVE_DETERMINATION_ID);
        if (!isExistedBeforeSave) {
            Determination beforeSaveDtm = new Determination();
            beforeSaveDtm.setID(BEFORESAVE_DETERMINATION_ID);
            beforeSaveDtm.setCode("DraftBeforeSaveDtm");
            beforeSaveDtm.setName("DraftBeforeSaveDtm");
            beforeSaveDtm.setComponentId(BEFORESAVE_COMPONENTID);
            beforeSaveDtm.setComponentName("DraftBeforeSaveDetermination");
            beforeSaveDtm.setTriggerTimePointType(EnumSet.of(BETriggerTimePointType.forValue(8)));
            beforeSaveDtm.setRequestNodeTriggerType(EnumSet.of(RequestNodeTriggerType.forValue(1)));

            be.getMainObject().getDeterminations().add(beforeSaveDtm);
        }
        boolean isExistedDelete = isExistedDtm(be, DELETE_DETERMINATION_ID);
        if (!isExistedDelete) {
            Determination deleteDtm = new Determination();
            deleteDtm.setID(DELETE_DETERMINATION_ID);
            deleteDtm.setCode("DraftDeleteDtm");
            deleteDtm.setName("DraftDeleteDtm");
            deleteDtm.setComponentId(DELETE_COMPONENTID);
            deleteDtm.setComponentName("DraftDeleteDetermination");
            deleteDtm.setTriggerTimePointType(EnumSet.of(BETriggerTimePointType.forValue(8)));
            deleteDtm.setRequestNodeTriggerType(EnumSet.of(RequestNodeTriggerType.forValue(4)));
            be.getMainObject().getDeterminations().add(deleteDtm);
        }
    }

    /**
     * 获取变量字段
     *
     * @param varCode 变量字段code
     * @param dataType 字段类型
     * @return 变量字段
     */
    private static CommonVariable getCommonVariable(String varCode, GspElementDataType dataType) {
        CommonVariable variable = new CommonVariable();
        variable.setID(UUID.randomUUID().toString());
        variable.setCode(varCode);
        variable.setName(varCode);
        variable.setMDataType(dataType);
        variable.setLabelID(varCode);
        variable.setLength(36);
        variable.setEnableRtrim(true);
        return variable;
    }

    /**
     * 添加变量字段
     *
     * @param be 业务实体
     */
    public static void addVariables(GspBusinessEntity be) {

        addVariable(be, "befTaskDraftBeId", GspElementDataType.String);
        addVariable(be, "befTaskDraftProcessCategory", GspElementDataType.String);
        addVariable(be, "befTaskDraftBizCategory", GspElementDataType.String);
        addVariable(be, "befTaskDraftSummary", GspElementDataType.String);
        addVariable(be, "befTaskDraftEnableDelDtm", GspElementDataType.Boolean);

    }

    /**
     * 添加变量字段
     *
     * @param be 业务实体
     * @param varCode 变量编号
     * @param dataType 字段类型
     */
    public static void addVariable(GspBusinessEntity be, String varCode, GspElementDataType dataType) {
        boolean isExistedVar = isExistedVariable(be, varCode);
        if (isExistedVar) {
            return;
        }
        CommonVariable var = getCommonVariable(varCode, dataType);
        be.getVariables().getContainElements().addField(var);
    }

    /**
     * 变量是否存在
     *
     * @param vm 实体
     * @param varCode 变量编号
     * @return 是否存在
     */
    private static boolean isExistedVariable(GspBusinessEntity vm, String varCode) {
        boolean isExistedVariable = false;
        if (vm.getVariables().getContainElements() == null
            || vm.getVariables().getContainElements().size() == 0) {
            isExistedVariable = false;
        }
        for (IGspCommonField variable : vm.getVariables().getContainElements()) {
            if (varCode.equals(variable.getCode())) {
                isExistedVariable = true;
                break;
            }
        }
        return isExistedVariable;
    }

}
